package com.fbs.wowo.forum.service.imp;

import com.fbs.wowo.essay.entity.Essay;
import com.fbs.wowo.essay.mapper.EssayMapper;
import com.fbs.wowo.forum.entity.Likes;
import com.fbs.wowo.forum.mapper.LikesMapper;
import com.fbs.wowo.forum.service.LikesService;
import com.fbs.wowo.util.common.Constants;
import com.fbs.wowo.util.common.Generator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 赞或踩
 * 赞：
 * 若没有赞 - 插入
 * 若已赞 - 取消赞
 * 若已赞并取消了 - 加上赞
 * 若赞后踩 - 先取消赞，然后踩
 *
 */
@Service("likesService")
@Transactional
public class LikesServiceImp implements LikesService {

    /**
     * 点赞
     *
     * 先判断这个赞是否在数据库已存在
     *
     * 不存在 - 创建，插入数据库
     * 获取当前这个实体的点赞数返回
     *
     * 存在 - 修改，判断之前是赞还是踩，若是和当前操作相同则取消之前的操作，若是和当前操作相反则取消之前的操作并覆盖为当前操作
     * 获取当前这个实体的点赞数返回
     *
     * @param likes like
     * @return 点赞数
     */
    @Override
    public Integer add(Likes likes) {
        // 通过点赞对象的id，类型和用户id唯一确定一个赞
        String likeEntity = likes.getLikeEntity();
        Integer likeType = likes.getLikeType();
        String userId = likes.getUserId();
        Likes likesDb = getLikes(likeEntity, likeType, userId);
        if (likesDb == null) {
            generateNewLike(likes, Constants.LIKES_STATUS_LIKE);
        } else {
            LikeAgain(likesDb, Constants.LIKES_STATUS_LIKE, Constants.LIKES_STATUS_HATE);
        }

        // 查询点赞数
        int count = count(likeEntity, likeType);
        //设置点赞数
        setLikeNum(likes,count);
        return count;
    }

    /**
     * 踩
     *
     * @param likes like
     * @return 点赞数
     */
    @Override
    public Integer minus(Likes likes) {
        // 通过点赞对象的id，类型和用户id唯一确定一个赞
        String likeEntity = likes.getLikeEntity();
        Integer likeType = likes.getLikeType();
        String userId = likes.getUserId();
        Likes likesDb = getLikes(likeEntity, likeType, userId);
        if (likesDb == null) {
            generateNewLike(likes, Constants.LIKES_STATUS_HATE);
        } else {
            LikeAgain(likesDb, Constants.LIKES_STATUS_HATE, Constants.LIKES_STATUS_LIKE);
        }

        // 查询点赞数
        int count = count(likeEntity, likeType);
        //设置点赞数
        setLikeNum(likes,count);
        return count;
    }

    /**
     * 更新作品的点赞数
     */
    public void setLikeNum(Likes likes,int count) {
        switch (likes.getLikeType()) {
            case 1:
                Essay essay = essayMapper.selectByPrimaryKey(likes.getLikeEntity());
                if (essay != null) {
                    essay.setLikeNum(count);
                    essayMapper.updateByPrimaryKeySelective(essay);
                }
                break;
            case 2:
                Essay voice = essayMapper.selectByPrimaryKey(likes.getLikeEntity());
                if (voice != null) {
                    voice.setLikeNum(count);
                    essayMapper.updateByPrimaryKeySelective(voice);
                }
                break;
        }
    }

    /**
     * 统计点赞数
     *
     * @param entityId   被点赞的实体（文章，专辑，主播，直播间等）
     * @param entityType 被点赞的类型（文章，专辑，主播，直播间等）
     * @return 点赞数
     */
    @Override
    public Integer likes(String entityId, Integer entityType) {
        return count(entityId, entityType);
    }

    /**
     * 按实体获取
     */
    public Likes getLikes(String likeEntity, Integer likeType, String userId) {
        return likesMapper.findByEntityAndUserId(likeEntity, likeType, userId);
    }

    /*******************************
     *
     * 私有方法
     *
     *******************************/

    /**
     * 创建新赞
     */
    private void generateNewLike(Likes likes, Integer likesStatus) {
        likes.setId(Generator.generateId());
        likes.setStatus(likesStatus);
        createLike(likes);
    }

    /**
     * 再赞
     */
    private void LikeAgain(Likes likesDb, Integer status1, Integer status2) {
        if (status1 == likesDb.getStatus()) {
            likesDb.setStatus(Constants.LIKES_STATUS_CANCEL);
        } else if (status2 == likesDb.getStatus() || Constants.LIKES_STATUS_CANCEL == likesDb.getStatus()) {
            likesDb.setStatus(status1);
        }
        modify(likesDb);
    }

    /*************************************************
     *
     * 底层实现
     *
     *************************************************/

    /**
     * 创建
     */
    private void createLike(Likes likes) {
        likesMapper.insertSelective(likes);
    }

    /**
     * 修改
     */
    private int modify(Likes likes) {
        return likesMapper.updateByPrimaryKeySelective(likes);
    }

    /**
     * 获取赞数
     */
    private Integer count(String likeEntity, Integer likeType) {
        return likesMapper.CountByEntity(likeEntity, likeType);
    }

    @Autowired
    private LikesMapper likesMapper;

    @Resource
    private EssayMapper essayMapper;

}
